<?php
// +----------------------------------------------------------------------
// | INPHP
// | Copyright (c) 2023 https://inphp.cc All rights reserved.
// | Licensed ( https://opensource.org/licenses/MIT )
// | Author: 幺月儿(https://gitee.com/lulanyin) Email: inphp@qq.com
// +----------------------------------------------------------------------
// | 账户表
// +----------------------------------------------------------------------
namespace app\sso\model;

use Inphp\Core\Config;
use Inphp\Core\Db\PDO\Model;
use Inphp\Core\Db\Redis;
use Inphp\Core\Modules;
use Inphp\Core\Services\Http\Cookie;
use Inphp\Core\Services\Http\Session;
use Inphp\Core\Util\Log;

class UserAuthModel extends Model
{
    /**
     * 表名
     * @var string
     */
    protected string $tableName = "sso_userAuth";

    /**
     * 主键字段
     * @var string
     */
    protected string $primaryKey = "id";


    /**
     * 给账号授权，并返回 Token 和 过期时间
     * @param int $uid
     * @param string $type
     * @param int $thirdPartyId
     * @param string|null $appId
     * @return array
     */
    public static function auth(int $uid, string $type = 'password', int $thirdPartyId = 0, ?string $appId = null): array
    {
        $config = Modules::getModule("sso")?->getConfig("auth");
        $lifeTime = $config["tokenLifeTime"] ?? 0;
        $lifeTime = is_numeric($lifeTime) && $lifeTime >= 3600 ? ceil($lifeTime) : 0;
        $data = [
            "uid"       => $uid,
            "ip"        => getIP(),
            "state"     => 1,
            "errorCode" => 0,
            "type"      => $type,
            "tpId"      => $thirdPartyId,
            "appId"     => $appId
        ];
        //生成 Token
        $token = hash_hmac("md5", time()."&".$uid, $data["ip"]);
        $token = strtoupper($token);
        if ($lifeTime > 0) {
            $data["expireTime"] = date("Y-m-d H:i:s", time() + $lifeTime);
        }
        $data["token"] = $token;
        //保存一份到数据
        @self::emptyQuery()->insert($data);
        //保存到缓存
        Redis::set("Token_{$token}", $uid, $lifeTime > 0 ? $lifeTime : -1);
        //如果非跨域等客户端，给客户端加一个 Cookie
        if (!getClient()->cross) {
            Cookie::set("token", $token, $lifeTime > 0 ? $lifeTime : 90 * 86400);
        }
        return [$token, $lifeTime];
    }

    /**
     * 检测Token是否存在
     * @param string $token
     * @return int
     */
    public static function tokenExists(string $token): int
    {
        $cache = Redis::get("Token_{$token}", 0);
        return is_numeric($cache) ? ceil($cache) : 0;
    }

    /**
     * 移除Token
     * @param string $token
     */
    public static function dropToken(string $token)
    {
        @Redis::del("Token_{$token}");
        Cookie::delete("token");
    }

    /**
     * 自动获取当前授权的账户信息
     * @return int
     */
    public static function checkUID(): int
    {
        $token = Cookie::get("token", Session::get("token"));
        if (empty($token)) {
            //从 header 中取
            $token = $client->header["TOKEN"] ?? null;
            if (empty($token)) {
                return 0;
            }
        }
        //从redis获取缓存
        return self::tokenExists($token);
    }
}